open Alcotest
open Seppo_lib

let set_up () =
  Mirage_crypto_rng_unix.use_default ();
  Unix.chdir "../../../test/"

(*
module SFT = struct
  let tc_to_string () =
    SF.(Boolean    true |> to_string) |> check string __LOC__ "?1";
    SF.(Boolean    false |> to_string) |> check string __LOC__ "?0";
    SF.(Date       Ptime.epoch |> to_string) |> check string __LOC__ "@0";
    SF.(Date       Ptime.min |> to_string) |> check string __LOC__ "@-62167219200";
    SF.(Date       Ptime.max |> to_string) |> check string __LOC__ "@253402300799";
    SF.(Integer    (-999_999_999_999_999L |> Optint.Int63.of_int64) |> to_string) |> check string __LOC__ "-999999999999999";
    SF.(Decimal    3.14 |> to_string) |> check string __LOC__ "3.14";
    SF.(String     "lorem ipsum!" |> to_string) |> check string __LOC__ "lorem ipsum!";
    SF.(Token      "t1" |> to_string) |> check string __LOC__ "t1";
    SF.(List       [of_int 23; of_int 42] |> to_string) |> check string __LOC__ "23, 42";
    SF.(Dictionary ["k1", of_int 23; "k2", of_int 42] |> to_string) |> check string __LOC__ "k1=23, k2=42";
    SF.(Dictionary ["b0", Boolean false; "b2", Boolean true] |> to_string) |> check string __LOC__ "b0=?0, b2";
    ()

  let tc_parse_string () =
    "-999_999_999_999_999" |> Optint.Int63.of_string |> Optint.Int63.to_int64 |> check int64 __LOC__ (-999999999999999L);
    let _ = SF.DisplayString "" in
    let _ = SF.Bytes (Bytes.make 0 '_')  in
    match "" |> SF.parse_string with
    | Error (_,_) -> () (* expected to fail for now *)
    | _ -> fail __LOC__
end
*)

module AS = struct
  open Angstrom
  let tc_rfc9561 () =
    {|1234|} |> parse_string ~consume:All Rfc9651.promille |> Result.get_ok |> check int __LOC__ 123;
    {|"%20"|} |> parse_string ~consume:All Rfc9651.sf_string |> Result.get_ok |> check Alcotest.string __LOC__ "%20";
    {|"%"|} |> parse_string ~consume:All Rfc9651.sf_string |> Result.get_ok |> check Alcotest.string __LOC__ "%";
    {|"uhu\\\"%20lol%"|} |> parse_string ~consume:All Rfc9651.sf_string |> Result.get_ok |> check Alcotest.string __LOC__ {|uhu\\"%20lol%|};
    {|uhu20lol|} |> parse_string ~consume:All Rfc9651.sf_token |> Result.get_ok |> check Alcotest.string __LOC__ {|uhu20lol|};
    {|1|} |> parse_string ~consume:All Rfc9651.promille |> Result.get_ok |> check int __LOC__ 100;
    (match {|12.3456|} |> parse_string ~consume:All Rfc9651.sf_decimal with
     | Ok (i,f) ->
       i |> check int __LOC__ 12;
       f |> check int __LOC__ 345
     | _ -> assert false
    );
    (match {|"uhu\\\"%20lol%"|} |> Rfc9651.parse_string with
     | Ok (`Sf_String v,[]) -> v |> check Alcotest.string __LOC__ {|uhu\\"%20lol%|};
     | _ -> assert false);

    (* https://www.rfc-editor.org/rfc/rfc9421#name-minimal-signature-using-rsa *)
    (match {|();created=1618884473;keyid="test-key-rsa-pss";nonce="b3k2pp5k7z-50gnwp.yemd"|}
           |> Rfc9651.parse_string with
    | Ok (`Sf_List [`Sf_Innerlist [],[k0,`Sf_Integer v0; k1,`Sf_String v1; k2,`Sf_String v2]],[]) ->
      k0 |> check Alcotest.string __LOC__ "created";
      v0 |> check int __LOC__ 1618884473;
      k1 |> check Alcotest.string __LOC__ "keyid";
      v1 |> check Alcotest.string __LOC__ "test-key-rsa-pss";
      k2 |> check Alcotest.string __LOC__ "nonce";
      v2 |> check Alcotest.string __LOC__ "b3k2pp5k7z-50gnwp.yemd";
      ()
    | _ -> failwith __LOC__ );
    (**)
    (match {|sig-b21=();created=1618884473;keyid="test-key-rsa-pss";nonce="b3k2pp5k7z-50gnwp.yemd"|}
           |> Rfc9651.(parse_string ~term:sf_dictionary) with
    | Ok (`Sf_Dictionary [(k,[]),(`Sf_Innerlist [],[k0,`Sf_Integer v0; k1,`Sf_String v1; k2,`Sf_String v2]) ], []) ->
      k |> check Alcotest.string __LOC__ "sig-b21";
      k0 |> check Alcotest.string __LOC__ "created";
      v0 |> check int __LOC__ 1618884473;
      k1 |> check Alcotest.string __LOC__ "keyid";
      v1 |> check Alcotest.string __LOC__ "test-key-rsa-pss";
      k2 |> check Alcotest.string __LOC__ "nonce";
      v2 |> check Alcotest.string __LOC__ "b3k2pp5k7z-50gnwp.yemd";
      ()
    | Error s -> s |> check Alcotest.string __LOC__ ""
    | _ -> failwith __LOC__ );
    (**)
    (match {|sig-b21=();created=@1618884473;keyid="test-key-rsa-pss";nonce="b3k2pp5k7z-50gnwp.yemd"|}
           |> Rfc9651.(parse_string ~term:sf_dictionary) with
    | Ok (`Sf_Dictionary [(k,[]),(`Sf_Innerlist [],[k0,`Sf_Date v0; k1,`Sf_String v1; k2,`Sf_String v2]) ], []) ->
      k |> check Alcotest.string __LOC__ "sig-b21";
      k0 |> check Alcotest.string __LOC__ "created";
      v0 |> Ptime.Span.to_int_s |> Option.get |> check int __LOC__ 1618884473;
      k1 |> check Alcotest.string __LOC__ "keyid";
      v1 |> check Alcotest.string __LOC__ "test-key-rsa-pss";
      k2 |> check Alcotest.string __LOC__ "nonce";
      v2 |> check Alcotest.string __LOC__ "b3k2pp5k7z-50gnwp.yemd";
      ()
    | Error s -> s |> check Alcotest.string __LOC__ ""
    | _ -> failwith __LOC__ );
    (**)
    (match {|sig-b21=:d2pmTvmbncD3xQm8E9ZV2828BjQWGgiwAaw5bAkgibUopemLJcWDy/lkbbHAve4cRAtx31Iq786U7it++wgGxbtRxf8Udx7zFZsckzXaJMkA7ChG52eSkFxykJeNqsrWH5S+oxNFlD4dzVuwe8DhTSja8xxbR/Z2cOGdCbzR72rgFWhzx2VjBqJzsPLMIQKhO4DGezXehhWwE56YCE+O6c0mKZsfxVrogUvA4HELjVKWmAvtl6UnCh8jYzuVG5WSb/QEVPnP5TmcAnLH1g+s++v6d4s8m0gCw1fV5/SITLq9mhho8K3+7EPYTU8IU1bLhdxO5Nyt8C8ssinQ98Xw9Q==:|}
           |> Rfc9651.(parse_string ~term:sf_dictionary) with
    | Ok (`Sf_Dictionary [(k,[]),(`Sf_Binary b,[]) ],[]) ->
      k |> check Alcotest.string __LOC__ "sig-b21";
      b |> Bytes.length |> check int __LOC__ 256;
      ()
    | Error s -> s |> check Alcotest.string __LOC__ ""
    | _ -> failwith __LOC__ );
(*
    (match {|"@signature-params": ();created=1618884473;keyid="test-key-rsa-pss";nonce="b3k2pp5k7z-50gnwp.yemd"|}
           |> parse_string ~consume:All sf_list with
    | Ok _ -> ()
    | _ -> failwith __LOC__ );
    *)
    ()
end

let () =
  run
    "seppo_suite" [
    __FILE__ , [
      "set_up",              `Quick, set_up;
      (* "SFT.tc_to_string",    `Quick, SFT.tc_to_string; *)
      (* "SFT.tc_parse_string", `Quick, SFT.tc_parse_string; *)
      "AS.tc_rfc9561",       `Quick, AS.tc_rfc9561;
    ]
  ]
